home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / TurboTCP 1.0.1 / TurboTCP.source / CTCPSessionDoc.cp < prev    next >
Text File  |  1993-12-10  |  22KB  |  989 lines

  1. /*
  2. ** CTCPSessionDoc.cp
  3. **
  4. **    TurboTCP support library
  5. **    TCP session document
  6. **
  7. **    Copyright © 1993, FrostByte Design / Eric Scouten
  8. **
  9. */
  10.  
  11.  
  12. #include "CTCPSessionDoc.h"
  13.  
  14. #ifndef TurboTCPHeaders
  15.     #include <pascal.h>
  16.     #include <Constants.h>
  17.     #include <TBUtilities.h>
  18.     #include <CDecorator.h>
  19.     #include <CError.h>
  20.     #include <CWindow.h>
  21. #endif
  22.  
  23. #include <CFile.h>
  24.  
  25. #include "CTCPResolverCall.h"
  26. #include "CTCPStream.h"
  27.  
  28.  
  29. #define sessionOpen (cState >= strSYNReceived) && (cState <= strTimeWait)
  30. #define sessionOpening (cState >= strListen) && (cState <= strSYNSent)
  31. #define sessionClosing (cState >= strFINWait1) && (cState <= strTimeWait)
  32.  
  33. #define ALRT_TCPOpenFailed    23000
  34. #define ALRT_TCPUnexpError    23001
  35. #define ALRT_TCPSendFailed    23002
  36. #define ALRT_TCPTerminated    23003
  37. #define ESTR_TerminBase        23010
  38.  
  39. #define STR__WindowStrings    23000
  40. #define Wstr_NoSession         1
  41. #define Wstr_Separator         2
  42. #define Wstr_NotReadyPrefix     3
  43. #define Wstr_NotReadySuffix     4
  44. #define Wstr_Untitled         5
  45. #define Wstr_PortDelimiter     6
  46.  
  47.  
  48. extern CDecorator    *gDecorator;
  49. extern CError         *gError;
  50.  
  51.  
  52. //    —— construction/destruction
  53.  
  54. /*______________________________________________________________________
  55. **
  56. ** ITCPSessionDoc
  57. **
  58. **    Initialize the document, including new instance variables.
  59. **
  60. **        aSupervisor (CApplication *):    the document’s supervisor
  61. **        printable (Boolean):            TRUE if document can be printed
  62. **        rcvBufferSize (long):        size of receive buffer to create
  63. **        theDefaultPort (b_16):        default IP port number
  64. **        doUseCName (Boolean):        TRUE to get canonical name of remote host
  65. **                                    whenever possible
  66. **        autoReceiveSize (short):        number of entries in RDS for auto-receive,
  67. **                                    0 to disable autoreceiving
  68. **        autoReceiveNum (short):        number of auto-receive calls to issue at once
  69. **                                    must be at least 1
  70. **
  71. */
  72.  
  73. void CTCPSessionDoc::ITCPSessionDoc (CApplication *aSupervisor, Boolean printable,
  74.                                 long rcvBufferSize, b_16 theDefaultPort,
  75.                                 Boolean doUseCName, short autoReceiveSize,
  76.                                 short autoReceiveNum)
  77.  
  78. {
  79.  
  80.     // blank out the usual variables
  81.     
  82.     itsStream = NULL;
  83.     itsResolver = NULL;
  84.     pendingOpenByName = closeAndQuit = FALSE;
  85.     actualPort = defaultPort = theDefaultPort;
  86.     hostCName[0] = '\0';
  87.     useCName = doUseCName;
  88.     sessionReady = FALSE;
  89.     goAwayOnClose = FALSE;
  90.     showFileName = TRUE;
  91.     showHostName = TRUE;
  92.     untitledNumber = 0;
  93.     
  94.     CDocument::IDocument(aSupervisor, printable);
  95.  
  96.  
  97.     // create a TCP stream
  98.  
  99.     TRY {
  100.         itsStream = new (CTCPStream);
  101.         itsStream->ITCPStream(rcvBufferSize, autoReceiveSize, autoReceiveNum);
  102.         itsResolver = new (CTCPResolverCall);
  103.         itsResolver->ITCPResolverCall();
  104.         DependUpon(itsStream);
  105.         DependUpon(itsResolver);
  106.     }
  107.     
  108.     CATCH {
  109.         ForgetObject(itsStream);
  110.         ForgetObject(itsResolver);
  111.     }
  112.     
  113.     ENDTRY;
  114.     
  115. }
  116.  
  117.  
  118. /*______________________________________________________________________
  119. **
  120. ** Dispose
  121. **
  122. **    Get rid of the document’s stream and resolver objects then dispose of self.
  123. **
  124. */
  125.  
  126. void CTCPSessionDoc::Dispose (void)
  127.  
  128. {
  129.  
  130.     // get rid of stream & resolver call objects
  131.  
  132.     if (itsStream) {
  133.         itsStream->InstallRcvBypass(NULL, NULL);
  134.         itsStream->PostponeDispose();
  135.     }
  136.     if (itsResolver)
  137.         itsResolver->Dispose();
  138.     
  139.     
  140.     // get rid of the session document object
  141.     
  142.     CDocument::Dispose();
  143.  
  144. }
  145.  
  146.  
  147. //    —— opening/closing session
  148.  
  149. /*______________________________________________________________________
  150. **
  151. ** OpenUserHost
  152. **
  153. **    Open a connection to the host named by the string. Hostname may be either dotted decimal
  154. **    notation or a DNS name. A port number may be specified at the end of the hostname
  155. **    (separated by a single space) if the caller permits it.
  156. **
  157. **        theHostName (char *):        the hostname (and optional port#) string
  158. **        theDefaultPort (b_16):        the default port number
  159. **        allowPortChange (Boolean):    TRUE to allow port number overrides
  160. **
  161. */
  162.  
  163. void CTCPSessionDoc::OpenUserHost (char *theHostName, b_16 theDefaultPort,
  164.                                 Boolean allowPortChange)
  165.  
  166. {
  167.     Str255        portNumStr;
  168.     long            newPortNum = 0;
  169.     register char    *s, *d;
  170.     register short    i;
  171.  
  172.  
  173.     // ensure that there is a host to open
  174.     
  175.     if (*theHostName == '\0') {
  176.         HandleOpenFailed(nameSyntaxErr);
  177.         return;
  178.     }
  179.  
  180.  
  181.     // parse for port number
  182.     
  183.     pendingPortNumber = theDefaultPort;
  184.     if (allowPortChange) {
  185.         s = theHostName;
  186.         d = (char *) &hostCName;
  187.         while ((*s != ' ') & (*s != '\0'))
  188.             *d++ = *s++;
  189.         *d = '\0';
  190.         if (*s == ' ') {
  191.             d = (char *) &portNumStr;
  192.             i = -1;
  193.             while (*s != '\0')
  194.                 *d++ = *s++, i++;
  195.             portNumStr[0] = (char) i;
  196.             if (i > 0)
  197.                 StringToNum(portNumStr, &newPortNum);
  198.         }
  199.     }
  200.     else
  201.         BlockMove(theHostName, &hostCName, 255);
  202.     
  203.     if (newPortNum != 0)
  204.         pendingPortNumber = newPortNum;
  205.  
  206.  
  207.     // issue resolver command
  208.     
  209.     pendingOpenByName = TRUE;
  210.     actualPort = pendingPortNumber;
  211.     itsResolver->DoStrToAddr((char *) &hostCName);
  212.     
  213. }
  214.  
  215.  
  216. /*______________________________________________________________________
  217. **
  218. ** Close
  219. **
  220. **    Close the document. This method also ensures that the TCP stream is gracefully
  221. **    closed. If not quitting, delays closure until the MacTCP says the stream has been
  222. **    terminated.
  223. **
  224. **        quitting (Boolean):    TRUE if quitting
  225. **
  226. **        return (Boolean):    FALSE if close/quit aborted by user
  227. **
  228. */
  229.  
  230. Boolean CTCPSessionDoc::Close (Boolean quitting)
  231.  
  232. {
  233.     Boolean    hadSessionOpen;
  234.     b_16        cState;
  235.  
  236.  
  237.     // find out if we really want to close
  238.  
  239.     closeAndQuit = quitting;
  240.     if (!ConfirmClose(quitting))
  241.         return(FALSE);
  242.  
  243.  
  244.     // yes, we’re really closing; take care of file first
  245.     
  246.     if (itsFile)
  247.         itsFile->Close();
  248.  
  249.  
  250.     // if session is open, give time for session to close
  251.     
  252.     if (itsStream) {
  253.         cState = itsStream->ConnectionState();
  254.         hadSessionOpen = sessionOpen;
  255.         if (sessionOpen)
  256.             itsStream->Close();
  257.         if (sessionOpening)
  258.             itsStream->Abort();
  259.     }
  260.     else
  261.         hadSessionOpen = FALSE;
  262.  
  263.  
  264.     // close the document – maybe?
  265.     
  266.     if (quitting || !hadSessionOpen || !goAwayOnClose)
  267.         return(CDirector::Close(quitting));
  268.     else
  269.         return(FALSE);
  270.  
  271. }
  272.  
  273.  
  274. //    —— document/window naming ——
  275.  
  276. /*______________________________________________________________________
  277. **
  278. ** AutoTitle
  279. **
  280. **    Call to automatically set the title for the session document window. Checks the connection
  281. **    status and host name and forms an appropriate title. Also updates the “sessionReady”
  282. **    field, so a quick test can be used to determine if data can be sent.
  283. **
  284. */
  285.  
  286. void CTCPSessionDoc::AutoTitle (void)
  287.  
  288. {
  289.     Str255    fileStr = "\p";
  290.     Str255    hostStr = "\p";
  291.     Str255    tempStr  = "\p";
  292.     Boolean    wasLocked = this->Lock(TRUE);
  293.  
  294.  
  295.     // sanity checking…
  296.     
  297.     if (!itsWindow) {
  298.         this->Lock(wasLocked);
  299.         return;
  300.     }
  301.     if (!untitledNumber)
  302.         untitledNumber = gDecorator->GetWCount();
  303.     if (itsStream)
  304.         sessionReady = ((hostCName[0] != '\0') && (itsStream->ConnectionState() == strEstablished));
  305.     else
  306.         sessionReady = FALSE;
  307.  
  308.  
  309.     // build document name string (if requested)
  310.     
  311.     if (showFileName) {
  312.         if (itsFile)
  313.             itsFile->GetName(fileStr);
  314.         else {
  315.             GetIndString(fileStr, STR__WindowStrings, Wstr_Untitled);
  316.             NumToString(untitledNumber, tempStr);
  317.             ConcatPStrings(fileStr, tempStr);
  318.         }
  319.     }
  320.  
  321.  
  322.     // build host name string
  323.  
  324.     if (showHostName) {
  325.         if (!hostCName[0])
  326.             GetIndString(hostStr, STR__WindowStrings, Wstr_NoSession);
  327.         else {
  328.             
  329.             if (!sessionReady)                        // left “(” if not ready
  330.                 GetIndString(hostStr, STR__WindowStrings, Wstr_NotReadyPrefix);
  331.                 
  332.             BlockMove(&hostCName, &tempStr, 255);    // host name, minus trailing “.”
  333.             CtoPstr((char *) &tempStr);
  334.             if (tempStr[tempStr[0]] == '.')
  335.                 tempStr[0]--;
  336.             ConcatPStrings(hostStr, tempStr);
  337.             
  338.             if (actualPort != defaultPort) {                // port number if non-standard
  339.                 GetIndString(tempStr, STR__WindowStrings, Wstr_PortDelimiter);
  340.                 ConcatPStrings(hostStr, tempStr);
  341.                 NumToString(actualPort, tempStr);
  342.                 ConcatPStrings(hostStr, tempStr);
  343.             }
  344.             
  345.             if (!sessionReady) {                        // right “)” if not ready
  346.                 GetIndString(tempStr, STR__WindowStrings, Wstr_NotReadySuffix);
  347.                 ConcatPStrings(hostStr, tempStr);
  348.             }
  349.             
  350.         }
  351.         
  352.         if (showFileName) {                            // “ : ” between file & host name
  353.             GetIndString(tempStr, STR__WindowStrings, Wstr_Separator);
  354.             ConcatPStrings(fileStr, tempStr);
  355.         }
  356.         ConcatPStrings(fileStr, hostStr);
  357.     }
  358.  
  359.  
  360.     // set the title
  361.  
  362.     if (showFileName || showHostName)                    // if neither file nor hostname are requested,
  363.                                                 //    assume subclass will specify window titles                    
  364.         itsWindow->SetTitle(fileStr);
  365.     this->Lock(wasLocked);
  366.     
  367. }
  368.  
  369.  
  370. /*______________________________________________________________________
  371. **
  372. ** GetName
  373. **
  374. **    Return the name of a document. Overriden to remove the behavior of checking the window
  375. **    title. Instead we use the file name, or an assigned “Untitled-nn” title.
  376. **
  377. **        theName (Str255):    where to return the name
  378. **
  379. */
  380.  
  381. void CTCPSessionDoc::GetName (Str255 theName)
  382.  
  383. {
  384.     Str255 tempStr;
  385.  
  386.     if (itsFile)
  387.         itsFile->GetName(theName);
  388.     else {
  389.         GetIndString(theName, STR__WindowStrings, Wstr_Untitled);
  390.         NumToString(untitledNumber, tempStr);
  391.         ConcatPStrings(theName,    tempStr);
  392.     }
  393. }
  394.     
  395.  
  396. /*______________________________________________________________________
  397. **
  398. ** SessionEstablished
  399. **
  400. **    Indicates whether a TCP session is established and ready for data.
  401. **
  402. **        return (Boolean):    TRUEif session is currently established
  403. **
  404. */
  405.  
  406. Boolean CTCPSessionDoc::SessionEstablished (void)
  407.  
  408. {
  409.     if (itsStream)
  410.         return (itsStream->ConnectionState() == strEstablished);
  411.     else
  412.         return FALSE;
  413. }
  414.  
  415.  
  416. //    —— special error handling ——
  417.  
  418. /*______________________________________________________________________
  419. **
  420. ** TCPErrorAlert
  421. **
  422. **    Display a customized message to indicate to the user that the connection failed. This
  423. **    routine is copied from the TCL’s routine ErrorAlert.
  424. **
  425. **        err (OSErr):        the error number
  426. **        message (long):        message code (same as for ErrorAlert, see <TCLUtilities.cp>
  427. **        alertID (short):        the ALRT/DITL resources to use
  428. **        parm3 (short):        the number to plug into ^3
  429. **
  430. **        return (short):        the item which caused the alert to return
  431. **
  432. */
  433.  
  434. short CTCPSessionDoc::TCPErrorAlert (OSErr err, long message, short alertID,
  435.                                 short parm3)
  436.  
  437. {
  438.     Str255    errStr;
  439.     Str255    hostStr;
  440.     Str63    numStr;
  441.     Str63    numStr3;
  442.     short    strIndex, strID;
  443.  
  444.  
  445.     // silence any further messages
  446.     
  447.     gLastError = kSilentErr;
  448.  
  449.  
  450.     // see if anyone filled in the message field
  451.     
  452.     errStr[0] = 0;
  453.     strIndex = LoShort(message);
  454.     
  455.     if (strIndex > 0) {
  456.         strID = HiShort(message);
  457.         if (strID == 0)
  458.             strID = STR_TCLfailMsgs;                // use built-in messages
  459.         else
  460.             strID += kUserFailMsgBase;            // use user’s message STR#
  461.         GetIndString(errStr, strID, strIndex);
  462.     }
  463.  
  464.  
  465.     // if still no message, check for 'Estr' resource
  466.         
  467.     if (errStr[0] == 0) {
  468.         StringHandle strH;
  469.          
  470.         strH = (StringHandle) GetResource(ErrMsg_Res, err);
  471.         if (!strH)
  472.              strH = GetString(STRosError2);
  473.          if (strH)
  474.              CopyPString(*strH, errStr);
  475.     }
  476.  
  477.  
  478.     // convert Mac error# and user’s host name to strings
  479.             
  480.     NumToString(err, numStr);
  481.     NumToString(parm3, numStr3);
  482.  
  483.     BlockMove(&hostCName, &hostStr, 255);
  484.     CtoPstr((char *) &hostStr);
  485.     if (hostStr[hostStr[0]] == '.')
  486.         hostStr[0]--;
  487.  
  488.     ParamText(errStr, numStr, hostStr, numStr3);
  489.  
  490.  
  491.     // avoid infinite recursion in error handling by specifically
  492.     //    testing if the ALRT and DITL resources we need are there
  493.         
  494.       if ((GetResource('ALRT', alertID) == NULL) ||
  495.           (GetResource('DITL', alertID) == NULL))
  496.       {
  497.           if (gError)
  498.                gError->MissingResources();
  499.            else
  500.                ExitToShell();            // nothing else we can do...
  501.        }
  502.    
  503.    
  504.        // show the error alert
  505.  
  506.     PositionDialog('ALRT', alertID);
  507.     InitCursor();
  508.     return (StopAlert(alertID, NULL));
  509.  
  510. }
  511.  
  512.  
  513. //    —— TCP notification routines ——
  514.  
  515. /*______________________________________________________________________
  516. **
  517. ** ProviderChanged
  518. **
  519. **    One of this object’s providers has just changed. Check to see if it is the TCP stream
  520. **    or resolver object. If so, process the notification.
  521. **
  522. **        aProvider (CCollaborator *):    the provider which changed
  523. **        reason (long):                the reason code which was provided
  524. **        info (void *):                additional info related to the reason
  525. **
  526. */
  527.  
  528. void CTCPSessionDoc::ProviderChanged (CCollaborator *aProvider, long reason, void *info)
  529.  
  530. {
  531.  
  532.     // find out who changed…
  533.  
  534.     if (aProvider == itsStream) {
  535.  
  536.         // it’s our stream, all right… find out what happened
  537.         
  538.         switch (reason) {
  539.             case tcpStreamClosed:
  540.                 HandleClosed();
  541.                 break;
  542.             case tcpStreamClosing:
  543.                 HandleClosing((Boolean) info);
  544.                 break;
  545.             case tcpStreamDataArrived:
  546.                 HandleDataArrived(((DataArrivedInfo *) info)->theData,
  547.                     ((DataArrivedInfo *) info)->theDataSize,
  548.                     ((DataArrivedInfo *) info)->isUrgent);
  549.                 break;
  550.             case tcpStreamDataSent:
  551.                 HandleDataSent((wdsEntry *) info);
  552.                 break;
  553.             case tcpStreamICMP:
  554.                 HandleICMP((struct ICMPReport *) info);
  555.                 break;
  556.             case tcpStreamOpened:
  557.                 HandleOpened();
  558.                 break;
  559.             case tcpStreamOpenFailed:
  560.                 HandleOpenFailed((OSErr) info);
  561.                 break;
  562.             case tcpStreamSendFailed:
  563.                 HandleSendFailed(((SendFailedInfo *) info)->WDSPtr,
  564.                     ((SendFailedInfo *) info)->theResultCode);
  565.                 break;
  566.             case tcpStreamTCPError:
  567.                 HandleTCPError(((TCPErrorInfo *) info)->theResultCode,
  568.                     ((TCPErrorInfo *) info)->theCsCode);
  569.                 break;
  570.             case tcpStreamTerminated:
  571.                 HandleTerminated(((TerminatedInfo *) info)->terminReason,
  572.                     ((TerminatedInfo *) info)->aboutToDispose);
  573.                 break;
  574.             case tcpStreamTimeout:
  575.                 HandleTimeout();
  576.                 break;
  577.             case tcpStreamUnexpectedData:
  578.                 HandleUnexpectedData();
  579.                 break;
  580.             case tcpStreamUrgentBegin:
  581.                 HandleUrgentBegin();
  582.                 break;
  583.         }
  584.     }
  585.     
  586.     else if (aProvider == itsResolver) {
  587.  
  588.         // it’s the resolver… find out what happened
  589.         
  590.         switch (reason) {
  591.             case tcpResolverStrToAddr:
  592.                 HandleStrToAddr((struct hostInfo *) info);
  593.                 break;
  594.             case tcpResolverAddrToName:
  595.                 HandleAddrToName((struct hostInfo *) info);
  596.                 break;
  597.             case tcpResolverHInfo:
  598.                 HandleHInfo((struct returnRec *) info);
  599.                 break;
  600.             case tcpResolverMXInfo:
  601.                 HandleMXInfo((struct returnRec *) info);
  602.                 break;
  603.         }
  604.     }
  605.     
  606.     else                                // not our stream, let someone else handle it…
  607.         CDocument::ProviderChanged(aProvider, reason, info);
  608.  
  609. }
  610.  
  611.  
  612. /*______________________________________________________________________
  613. **
  614. ** HandleClosed (protected method)
  615. **
  616. **    Respond to notification that the session has closed.
  617. **
  618. */
  619.  
  620. void CTCPSessionDoc::HandleClosed (void)
  621.  
  622. {
  623.     // null method
  624. }
  625.  
  626.  
  627. /*______________________________________________________________________
  628. **
  629. ** HandleClosing (protected method)
  630. **
  631. **    Respond to notification that the session is being closed.
  632. **
  633. **        remoteClosing (Boolean):    TRUE if close initiated by remote host
  634. **
  635. */
  636.  
  637. void CTCPSessionDoc::HandleClosing (Boolean remoteClosing)
  638.  
  639. {
  640.     b_16        cState;
  641.  
  642.     AutoTitle();
  643.     if (remoteClosing) {
  644.         if (goAwayOnClose)
  645.             Close(FALSE);
  646.         else {
  647.             if (itsStream) {                        // make sure that we disconnect even if window remains
  648.                 cState = itsStream->ConnectionState();
  649.                 if (sessionOpen)
  650.                     itsStream->Close();
  651.                 if (sessionOpening)
  652.                     itsStream->Abort();
  653.             }
  654.         }
  655.     }
  656. }
  657.  
  658.  
  659. /*______________________________________________________________________
  660. **
  661. ** HandleDataArrived (protected method)
  662. **
  663. **    Process notification that data has arrived.
  664. **
  665. **        theData (Ptr):        pointer to the data
  666. **        theDataSize (b_16):    size of data buffer
  667. **        isUrgent (Boolean):    TRUE if urgent mode is on
  668. **
  669. */
  670.  
  671. void CTCPSessionDoc::HandleDataArrived (Ptr theData, b_16 theDataSize, Boolean isUrgent)
  672.  
  673. {
  674.     // null method
  675. }
  676.  
  677.  
  678. /*______________________________________________________________________
  679. **
  680. ** HandleDataSent (protected method)
  681. **
  682. **    Respond to notification that data has been successfully sent.
  683. **
  684. **        WDSPtr (wdsEntry *):    the WDS for the data which was sent
  685. **
  686. */
  687.  
  688. void CTCPSessionDoc::HandleDataSent (wdsEntry *WDSPtr)
  689.  
  690. {
  691.     // null method
  692. }
  693.  
  694.  
  695. /*______________________________________________________________________
  696. **
  697. ** HandleICMP (protected method)
  698. **
  699. **    Respond to an ICMP message which was received.
  700. **
  701. **        icmpMsg (struct ICMPReport *):    the ICMP message report
  702. **
  703. */
  704.  
  705. void CTCPSessionDoc::HandleICMP (struct ICMPReport *icmpMsg)
  706.  
  707. {
  708.     // null method
  709.  
  710. }
  711.  
  712.  
  713. /*______________________________________________________________________
  714. **
  715. ** HandleOpened (protected method)
  716. **
  717. **    Respond to successful completion of a TCPPassiveOpen or TCPActiveOpen command.
  718. **
  719. */
  720.  
  721. void CTCPSessionDoc::HandleOpened (void)
  722.  
  723. {
  724.     actualPort = itsStream->itsRemotePort;
  725.     AutoTitle();
  726. }
  727.  
  728.  
  729. /*______________________________________________________________________
  730. **
  731. ** HandleOpenFailed (protected method)
  732. **
  733. **    Respond to notification that a TCPOpen command failed.
  734. **
  735. **        theResultCode (OSErr):    the reason for failure
  736. */
  737.  
  738. void CTCPSessionDoc::HandleOpenFailed (OSErr theResultCode)
  739.  
  740. {
  741.     TCPErrorAlert(theResultCode, 0L, ALRT_TCPOpenFailed, 1);
  742.     Close(FALSE);
  743.     FailOSErr(kSilentErr);    
  744. }
  745.  
  746.  
  747. /*______________________________________________________________________
  748. **
  749. ** HandleSendFailed (protected method)
  750. **
  751. **    Respond to failure to send data. This can be overriden to retry the send; however, you
  752. **    must be careful to duplicate the WDS since CTCPStream::HandleSendFailed disposes of
  753. **    the WDS and its contents after calling this routine.
  754. **
  755. **        WDSPtr (wdsEntry *):    the WDS structure for the data that wasn’t sent
  756. **        theResultCode (OSErr):    the reason for failure
  757. **
  758. */
  759.  
  760. void CTCPSessionDoc::HandleSendFailed (wdsEntry *WDSPtr, OSErr theResultCode)
  761.  
  762. {
  763.     TCPErrorAlert(theResultCode, 0L, ALRT_TCPSendFailed, 0);
  764. }
  765.  
  766.  
  767. /*______________________________________________________________________
  768. **
  769. ** HandleTCPError (protected method)
  770. **
  771. **    Respond to failure of a TCP command that was not expected. Default method displays a
  772. **    dialog, but takes no other action.
  773. **
  774. **        theResultCode (OSErr):    the result code
  775. **        theCsCode (short):        the TCP command number that failed
  776. **
  777. */
  778.  
  779. void CTCPSessionDoc::HandleTCPError (OSErr theResultCode, short theCsCode)
  780.  
  781. {
  782.     TCPErrorAlert(theResultCode, 0L, ALRT_TCPUnexpError, theCsCode);
  783. }
  784.  
  785.  
  786. /*______________________________________________________________________
  787. **
  788. ** HandleTerminated (protected method)
  789. **
  790. **    Respond to session termination event.
  791. **
  792. **        terminReason (b_16):    reason for termination (see TCP dev guide, p93)
  793. **        aboutToDispose (Boolean):    TRUE if TCP stream will now dispose of itself
  794. **
  795. */
  796.  
  797. void CTCPSessionDoc::HandleTerminated (b_16 terminReason, Boolean aboutToDispose)
  798.  
  799. {
  800.  
  801.     // display error alert unless due to normal closure
  802.     
  803.     if ((terminReason != 6) && (terminReason != 7))
  804.         TCPErrorAlert(terminReason + ESTR_TerminBase, 0L, ALRT_TCPTerminated, 0);
  805.  
  806.  
  807.     // retitle window & close if requested
  808.  
  809.     AutoTitle();
  810.     if (goAwayOnClose)
  811.         Close(closeAndQuit);
  812.  
  813.  
  814.     // mark TCP stream as gone if appropriate
  815.     
  816.     if (aboutToDispose)
  817.         itsStream = NULL;
  818.  
  819. }
  820.  
  821.  
  822. /*______________________________________________________________________
  823. **
  824. ** HandleTimeout (protected method)
  825. **
  826. **    Respond to a ULP timeout event (remote TCP failed to respond in time). This method is
  827. **    only called if the ULP timeout action is set to abort & notify.
  828. **
  829. */
  830.  
  831. void CTCPSessionDoc::HandleTimeout (void)
  832.  
  833. {
  834.     // null method
  835. }
  836.  
  837.  
  838. /*______________________________________________________________________
  839. **
  840. ** HandleUnexpectedData (protected method)
  841. **
  842. **    Respond to notification that data arrived without a receive command. If auto-receive is
  843. **    used, this method should never be called.
  844. **
  845. */
  846.  
  847. void CTCPSessionDoc::HandleUnexpectedData (void)
  848.  
  849. {
  850.     // null method
  851. }
  852.  
  853.  
  854. /*______________________________________________________________________
  855. **
  856. ** HandleUrgentBegin (protected method)
  857. **
  858. **    Respond to notification that urgent data is arriving.
  859. **
  860. */
  861.  
  862. void CTCPSessionDoc::HandleUrgentBegin (void)
  863.  
  864. {
  865.     // null method
  866. }
  867.  
  868.  
  869. /*______________________________________________________________________
  870. **
  871. ** HandleStrToAddr (protected method)
  872. **
  873. **    Respond to nofitication that a resolver StrToAddr call has completed. Most of this code
  874. **    is written to complete the OpenUserHost method. If OpenUserHost was issued, this method
  875. **    proceeds to establish a connection with the IP host which was named by the user.
  876. **
  877. **        theHostInfo (struct hostInfo *):    the hostInfo record (see MacTCP Dev Guide, p70)
  878. **
  879. */
  880.  
  881. void CTCPSessionDoc::HandleStrToAddr (struct hostInfo *theHostInfo)
  882.  
  883. {
  884.  
  885.     // if OpenUserHost was issued, finish the job
  886.     
  887.     if ((pendingOpenByName) && (itsStream)) {
  888.         if ((*theHostInfo).rtnCode == noErr) {
  889.  
  890.  
  891.             // success, open the connection
  892.             
  893.             hostAddress = (*theHostInfo).addr[0];
  894.             pendingOpenByName = FALSE;
  895.             itsStream->OpenConnection(FALSE, hostAddress,
  896.                     pendingPortNumber, 0);
  897.  
  898.  
  899.             // if desired, get the canonical name
  900.             
  901.             if (useCName) {
  902.                 if ((*theHostInfo).cname[0] == 0) {
  903.                     itsResolver->DoAddrToName(hostAddress);
  904.                     pendingOpenByName = TRUE;
  905.                 }
  906.                 else
  907.                     BlockMove(&(*theHostInfo).cname, &hostCName, 255);
  908.             }
  909.  
  910.  
  911.             // set the window title to reflect the name
  912.             
  913.             AutoTitle();
  914.  
  915.         } else {
  916.  
  917.  
  918.             // failed, issue alert & quit
  919.  
  920.             pendingOpenByName = FALSE;
  921.             HandleOpenFailed((*theHostInfo).rtnCode);
  922.  
  923.         } // if (...noErr)
  924.     } // if (pendingOpenByName)
  925.     
  926. }
  927.  
  928.  
  929. /*______________________________________________________________________
  930. **
  931. ** HandleAddrToName (protected method)
  932. **
  933. **    Respond to nofitication that a resolver AddrToName call has completed.
  934. **
  935. **        theHostInfo (struct hostInfo *):    the hostInfo record (see MacTCP Dev Guide, p75)
  936. **
  937. */
  938.  
  939. void CTCPSessionDoc::HandleAddrToName (struct hostInfo *theHostInfo)
  940.  
  941. {
  942.  
  943.     // if OpenUserHost was issued, grab the hostname
  944.     
  945.     if ((pendingOpenByName) && (useCName)) {
  946.         if ((*theHostInfo).rtnCode == noErr) {
  947.             pendingOpenByName = FALSE;
  948.             if ((*theHostInfo).cname[0])
  949.                 BlockMove(&(*theHostInfo).cname, &hostCName, 255);
  950.             AutoTitle();
  951.         }
  952.     }
  953.  
  954. }
  955.  
  956.  
  957. /*______________________________________________________________________
  958. **
  959. ** HandleHInfo (protected method)
  960. **
  961. **    Respond to nofitication that a resolver HInfo call has completed.
  962. **
  963. **        theHInfo (struct returnRec *):    the returnRec record (see MacTCP Dev Guide, p76)
  964. **
  965. */
  966.  
  967. void CTCPSessionDoc::HandleHInfo (struct returnRec *theHInfo)
  968.  
  969. {
  970.     // null method
  971. }
  972.  
  973.  
  974. /*______________________________________________________________________
  975. **
  976. ** HandleMXInfo (protected method)
  977. **
  978. **    Respond to nofitication that a resolver MXInfo call has completed.
  979. **
  980. **        theMXInfo (struct returnRec *):    the returnRec record (see MacTCP Dev Guide, p77)
  981. **
  982. */
  983.  
  984. void CTCPSessionDoc::HandleMXInfo (struct returnRec *theMXInfo)
  985.  
  986. {
  987.     // null method
  988. }
  989.